package jwt

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/golang-jwt/jwt/v5" // JWT处理库
	"log"
	"net/http"
	"time"
)

var mySigningKey = []byte("AllYourBase") //签名秘钥
type MyCustomClaims struct {
	UserId               uint `json:"user_id"` // 自定义字段，存储用户ID
	jwt.RegisteredClaims      // 嵌入JWT标准声明
}

func NewWithClaims(UserID uint) (string, error) {
	// 创建自定义声明实例
	claims := MyCustomClaims{
		UserID, // 设置用户ID
		jwt.RegisteredClaims{
			// 设置令牌过期时间为24小时后
			ExpiresAt: jwt.NewNumericDate(time.Now().Add(24 * time.Hour)),
			Issuer:    "test", // 设置令牌发行者
		},
	}
	// 使用HS256算法创建令牌
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	// 使用签名密钥对令牌进行签名并返回字符串
	return token.SignedString(mySigningKey)
}
func ParseToken(tokenString string) (*MyCustomClaims, error) {
	// 解析令牌字符串
	token, err := jwt.ParseWithClaims(tokenString, &MyCustomClaims{}, func(token *jwt.Token) (interface{}, error) {
		return mySigningKey, nil // 提供签名密钥用于验证
	})
	if err != nil {
		log.Fatal(err) // 解析错误时输出日志并退出
	} else if claims, ok := token.Claims.(*MyCustomClaims); ok {
		// 解析成功且类型正确，打印用户ID和发行者
		fmt.Println(claims.UserId, claims.RegisteredClaims.Issuer)
		return claims, nil // 返回解析得到的声明
	} else {
		log.Fatal("unknown claims type, cannot proceed") // 声明类型错误时输出日志并退出
	}
	return nil, err
}
func GetToken() gin.HandlerFunc {
	return func(c *gin.Context) {
		// 从请求头中获取名为"token"的字段
		tokenString := c.GetHeader("token")
		if tokenString == "" {
			// 如果没有提供令牌，返回401未授权错误
			c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "未提供认证令牌"})
			return
		}
		// 解析令牌
		claims, err := ParseToken(tokenString)
		if err != nil {
			// 令牌无效时返回401未授权错误
			c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "无效令牌"})
			return
		}
		// 将用户ID存入上下文，供后续处理函数使用
		c.Set("user_id", claims.UserId)
		c.Next() // 调用下一个中间件或处理函数
	}
}
